import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
from collections import deque
import threading
import time
from typing import Dict, List, Tuple

class RealtimePlotter:
    """实时数据绘图工具"""
    
    def __init__(self, max_points: int = 100, update_interval: int = 100):
        """
        初始化实时绘图器
        :param max_points: 最大显示数据点数量
        :param update_interval: 更新间隔（毫秒）
        """
        self.max_points = max_points
        self.update_interval = update_interval
        self.data = {}  # 存储数据: {标签: deque}
        self.fig, self.ax = plt.subplots(figsize=(10, 6))
        self.lines = {}  # 存储线条: {标签: Line2D}
        self.running = False
        self.thread = None
        self.lock = threading.Lock()
    
    def add_series(self, label: str, color: str = None):
        """添加一个数据系列"""
        with self.lock:
            if label not in self.data:
                self.data[label] = deque(maxlen=self.max_points)
                line, = self.ax.plot([], [], label=label, color=color)
                self.lines[label] = line
                self.ax.legend()
    
    def update_data(self, label: str, value: float):
        """更新数据系列"""
        with self.lock:
            if label in self.data:
                self.data[label].append(value)
    
    def _update_plot(self, frame):
        """更新绘图（由动画调用）"""
        with self.lock:
            # 更新所有线条数据
            for label, line in self.lines.items():
                x_data = np.arange(len(self.data[label]))
                y_data = np.array(self.data[label])
                line.set_data(x_data, y_data)
            
            # 调整坐标轴范围
            self.ax.relim()
            self.ax.autoscale_view()
        
        return self.lines.values()
    
    def start(self, title: str = "实时数据监控", xlabel: str = "时间", ylabel: str = "值"):
        """启动实时绘图"""
        self.ax.set_title(title)
        self.ax.set_xlabel(xlabel)
        self.ax.set_ylabel(ylabel)
        self.ax.grid(True)
        
        self.running = True
        self.ani = animation.FuncAnimation(
            self.fig,
            self._update_plot,
            interval=self.update_interval,
            blit=True
        )
        
        # 在单独线程中运行绘图
        self.thread = threading.Thread(target=plt.show, daemon=True)
        self.thread.start()
        print("实时绘图已启动")
    
    def stop(self):
        """停止实时绘图"""
        self.running = False
        plt.close(self.fig)
        if self.thread:
            self.thread.join()
        print("实时绘图已停止")

# 使用示例
if __name__ == "__main__":
    plotter = RealtimePlotter(max_points=50)
    plotter.add_series("CPU使用率", "blue")
    plotter.add_series("内存使用率", "red")
    plotter.start(title="系统资源监控")
    
    # 模拟数据更新
    try:
        while True:
            # 随机生成模拟数据
            cpu_usage = np.random.uniform(10, 80)
            mem_usage = np.random.uniform(20, 90)
            
            plotter.update_data("CPU使用率", cpu_usage)
            plotter.update_data("内存使用率", mem_usage)
            time.sleep(0.5)
    except KeyboardInterrupt:
        plotter.stop()